package com.hare.system_server.serice.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hare.auth.utils.SecurityUtils;
import com.hare.common.exception.ServiceException;
import com.hare.common.utils.AssertUtils;
import com.hare.common.utils.PageUtils;
import com.hare.system_api.dto.SysRoleDTO;
import com.hare.system_api.po.SysAdminRole;
import com.hare.system_api.po.SysRole;
import com.hare.system_api.po.SysRoleMenu;
import com.hare.system_api.vo.SysRoleVO;
import com.hare.system_server.mapper.SysAdminRoleMapper;
import com.hare.system_server.mapper.SysRoleMapper;
import com.hare.system_server.mapper.SysRoleMenuMapper;
import com.hare.system_server.serice.SysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: Hare
 * @description: 角色实现Service
 * @author: Hare
 * @create: 2022-11-14 14:53
 * @Version 6.0.1
 **/
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Autowired
    SysRoleMapper sysRoleMapper;

    @Autowired
    SysRoleMenuMapper sysRoleMenuMapper;

    @Autowired
    SysAdminRoleMapper sysAdminRoleMapper;


    /**
     * 角色管理==> 查询角色信息(分页)
     *
     * @param dto 角色信息
     * @return
     */
    @Override
    public PageUtils<SysRoleVO> pageRoleInfo(SysRoleDTO dto) {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().like(StrUtil.isNotEmpty(dto.getRoleName()), SysRole::getRoleName, dto.getRoleName())
                .eq(dto.getStatus() != null, SysRole::getStatus, dto.getStatus());
        IPage<SysRole> page = sysRoleMapper.selectPage(new Page<>(dto.getPageIndex(), dto.getPageSize()), queryWrapper);

        List<SysRoleVO> roleList = page.getRecords().stream().map(item -> {
            SysRoleVO sysRoleVO = new SysRoleVO();
            sysRoleVO.setCreateTime(item.getCreateTime())
                    .setId(item.getId())
                    .setRoleName(item.getRoleName())
                    .setStatus(item.getStatus())
                    .setCreateBy(item.getCreateBy())
                    .setUpdateTime(item.getUpdateTime());
            return sysRoleVO;
        }).collect(Collectors.toList());

        return new PageUtils<>(roleList, page.getTotal(), page.getSize(), page.getCurrent());
    }


    /**
     * 查询相关角色信息
     *
     * @param dto
     * @return
     */
    @Override
    public List<SysRoleVO> roleInfoQuery(SysRoleDTO dto) {
        return sysRoleMapper.roleInfoQuery(dto);
    }


    /**
     * 角色管理=> 修改角色信息
     *
     * @param dto
     * @return
     */
    @Override
    public int updateRoleStatus(SysRoleDTO dto) {
        SysRole sysRole = new SysRole();
        sysRole.setStatus(dto.getStatus());
        sysRole.setId(dto.getId());
        return sysRoleMapper.updateById(sysRole);
    }

    /**
     * 角色管理=> 新增or修改角色信息
     *
     * @param sysRoleDTO 角色信息
     * @return
     */
    @Override
    @Transactional
    public int insertOrUpdate(SysRoleDTO sysRoleDTO) {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysRole::getRoleName, sysRoleDTO.getRoleName());
        SysRole sysRoleInfo = sysRoleMapper.selectOne(queryWrapper);
        if (!sysRoleDTO.isInsert()) {
            if (!sysRoleInfo.getId().equals(sysRoleDTO.getId())) {
                AssertUtils.isTrue(ObjectUtil.isNotNull(sysRoleInfo), "修改 " + sysRoleDTO.getRoleName() + " 角色重复");
            }
        } else {
            AssertUtils.isTrue(ObjectUtil.isNotNull(sysRoleInfo), "新增 " + sysRoleDTO.getRoleName() + " 角色重复");
        }
        if (sysRoleDTO.isInsert()) {
            // 新增
            SysRole sysRole = new SysRole();
            sysRole.setStatus(sysRoleDTO.getStatus());
            sysRole.setRoleName(sysRoleDTO.getRoleName());
            sysRoleMapper.insert(sysRole);

            List<SysRoleMenu> sysRoleMenus = new ArrayList<>();
            sysRoleDTO.getMenuIdList().forEach(item -> {
                SysRoleMenu sysRoleMenu = new SysRoleMenu();
                sysRoleMenu.setMenuId(item);
                sysRoleMenu.setRoleId(sysRole.getId());
                sysRoleMenus.add(sysRoleMenu);
            });
            return sysRoleMenuMapper.saveBatchRoleMenu(sysRoleMenus);
        } else {
            //修改
            this.checkUserAllowed(sysRoleDTO);
            SysRole sysRole = new SysRole();
            sysRole.setStatus(sysRoleDTO.getStatus());
            sysRole.setRoleName(sysRoleDTO.getRoleName());
            sysRole.setId(sysRoleDTO.getId());
            sysRoleMapper.updateById(sysRole);

            QueryWrapper<SysRoleMenu> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(StrUtil.isNotEmpty(sysRoleInfo.getId()), SysRoleMenu::getRoleId, sysRoleInfo.getId());
            sysRoleMenuMapper.delete(wrapper);

            List<SysRoleMenu> sysRoleMenus = new ArrayList<>();
            sysRoleDTO.getMenuIdList().forEach(item -> {
                SysRoleMenu sysRoleMenu = new SysRoleMenu();
                sysRoleMenu.setMenuId(item);
                sysRoleMenu.setRoleId(sysRoleDTO.getId());
                sysRoleMenus.add(sysRoleMenu);
            });
            return sysRoleMenuMapper.saveBatchRoleMenu(sysRoleMenus);
        }
    }


    /**
     * 根据角色id 删除角色信息
     *
     * @param sysRoleDTO 角色信息
     * @return
     */
    @Override
    @Transactional
    public int deleteRole(SysRoleDTO sysRoleDTO) {
        //检查是否是超级管理员角色
        this.checkUserAllowed(sysRoleDTO);
        //检查是否已经是分配过的角色
        QueryWrapper<SysAdminRole> queryWrappers = new QueryWrapper<>();
        queryWrappers.lambda().eq(StrUtil.isNotEmpty(sysRoleDTO.getId()), SysAdminRole::getRoleId, sysRoleDTO.getId());
        Long countDistribution = sysAdminRoleMapper.selectCount(queryWrappers);
        if (countDistribution > 0) {
            SysRole sysRole = sysRoleMapper.selectById(sysRoleDTO.getId());
            throw new ServiceException(String.format("%s角色已分配，无法删除", sysRole.getRoleName()));
        }

        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysRoleMenu::getRoleId, sysRoleDTO.getId());
        sysRoleMenuMapper.delete(queryWrapper);
        return sysRoleMapper.deleteById(sysRoleDTO.getId());
    }

    /**
     * 校验角色是否允许操作
     *
     * @param role 角色信息
     */
    @Override
    public void checkUserAllowed(SysRoleDTO role) {
        if (StrUtil.isNotEmpty(role.getId()) && SecurityUtils.isAdminRole(role.getId())) {
            throw new ServiceException("不允许操作超级管理员角色");
        }
    }


    /**
     * 根据角色id查询角色信息
     *
     * @param dto 角色信息
     * @return
     */
    @Override
    public SysRoleVO getRoleInf(SysRoleDTO dto) {
        return sysRoleMapper.getRoleInf(dto);
    }
}
